import { Color, Mark } from "./enum";
import { Card, Jocker } from "./type";

interface PublishResult {
  player1: Deck;
  player2: Deck;
  player3: Deck;
  left: Deck;
}

export class Deck {
  private cards: Card[] = [];

  constructor(cards?: Card[]) {
    if (cards) {
      this.cards = cards;
    } else {
      this.init();
    }
  }

  private init() {
    // Object.values()会运行才能知道marks，而在运行过程中ts会被删除，因此此时这里为any类型
    const marks = Object.values(Mark);
    const colors = Object.values(Color);

    for (const m of marks) {
      for (const c of colors) {
        this.cards.push(<Card>{
          mark: m,
          color: c,
          getString() {
            return this.color + this.mark;
          },
        });
      }
    }

    const jo: Jocker = {
      type: "small",
      getString() {
        return "jo";
      },
    };
    this.cards.push(jo);

    const jocker: Jocker = {
      type: "big",
      getString() {
        return "jocker";
      },
    };

    this.cards.push(jocker);
  }

  print() {
    let result = "\n";
    this.cards.forEach((card, i) => {
      result += card.getString() + "\t";
      if ((i + 1) % 6 === 0) {
        result += "\n";
      }
    });
    console.log(result);
  }

  shuffle() {
    const len = this.cards.length;
    for (let i = 0; i < len; i++) {
      const targetIndex = this.getRandom(0, len);
      const temp = this.cards[i];
      this.cards[i] = this.cards[targetIndex];
      this.cards[targetIndex] = temp;
    }
  }

  /*  publish(): [Deck, Deck, Deck, Deck] {
    let player1: Deck, player2: Deck, player3: Deck, left: Deck;
    player1 = this.takeCards(17);
    player2 = this.takeCards(17);
    player3 = this.takeCards(17);
    left = new Deck(this.cards);

    return [player1, player2, player3, left];
  } */

  publish(): PublishResult {
    let player1: Deck, player2: Deck, player3: Deck, left: Deck;
    player1 = this.takeCards(17);
    player2 = this.takeCards(17);
    player3 = this.takeCards(17);
    left = new Deck(this.cards);

    return {
      player1,
      player2,
      player3,
      left,
    };
  }

  private takeCards(n: number): Deck {
    const cards: Card[] = [];
    for (let i = 0; i < n; i++) {
      cards.push(this.cards.shift() as Card);
    }
    return new Deck(cards);
  }

  private getRandom(min: number, max: number) {
    return Math.floor(Math.random() * (max - min) + min);
  }
}
